import Dingo.API as api
import random

__author__ = "Sarah Mount"

class TheSimulation(api.Simulation):
	def __init__(self, graph):
		ether = api.Ether(self)
		api.Ether.RF_radius = 500
		num_nodes = 5
		b_sensor = BroadcastingSensor(graph, ether, -1, num_nodes)
		sensors = [ReceivingSensor(graph, ether, i, num_nodes) for i in xrange(num_nodes)]
		sensors.append(b_sensor)
		api.Simulation.__init__(self, sensors, graph)
	def run(self):
		super(TheSimulation, self).run()
	
class BroadcastingSensor(api.Sensor):
	def __init__(self, graph, ether, i, num_nodes):
		x = 200
		y = 200
		api.Sensor.__init__(self, graph, "Sensor[%d]" % i, (x, y), api.SensorColor.White, api.Scheduler([BroadcastTask(self)], -1), ether)
		return

class ReceivingSensor(api.Sensor):
	def __init__(self, graph, ether, i, num_nodes):
		x = random.randrange(400)
		y = random.randrange(500)
		api.Sensor.__init__(self, graph, "Sensor[%d]" % i, (x, y), api.SensorColor.Grey, api.Scheduler([RecvTask(self)], -1), ether)
		return


class ColourBroadcastPacket(api.Packet):
	"""Defines packets to be sent across the network.
	This one just sends sensor colours. When a sensor receives
	a message, it should change colour according to the message
	it's received.
	"""
	def __init__(self, sender, msg):
		### sending node, receiving node, message_object
		### NOTE that we haven't given a receiving object,
		### because these packets will be broadcast
		api.Packet.__init__(self, sender, None, msg)
		return

class BroadcastTask(api.Task):
	"""Broadcast a ColourPacket to all sensors."""
	def __init__(self, sensor):
		# self, priority, repetitions, ref-to-sensor
		api.Task.__init__(self, 0, 1, sensor)
	def task(self):
		### Real work
		rgb = random.randrange(1<<24)
		colour = api.SensorColor.FromRGBCombined(rgb)
		packet = ColourBroadcastPacket(self.sensor.id, colour)
		### Broadcast packet
		print "Sensor broadcasting"# % (self.sensor.id)
		self.sensor.broadcast(api.SensorColor.FromName("Green"), None, packet)
		### Sleeeeep
		sleeptime = random.uniform(2, 3)
		api.Sleep(sleeptime)
		return

class RecvTask(api.Task):
	"""Iterate over recv_q; retrieve packets and change colour."""
	def __init__(self, sensor):
		# self, priority, repetitions, ref-to-sensor
		api.Task.__init__(self, 0, 2, sensor)
	def task(self):
		### Debug info
		node = self.sensor.node # graphical sensor
		node.SetNodeColour(api.SensorColor.FromName("Black"))
		### Real work
		while not self.sensor.recv_q.empty(): # If there are any messages
			msg = self.sensor.recv_q.get()
			print_info = (self.sensor.id, msg.sender_id, msg.time_sent, msg.rssi)
			print "%s found packet from %s set at %.3f with RSSI %f" % print_info
			node.SetNodeColour(msg.msg)
			### Sleeep
			sleeptime = random.uniform(1, 2)
			api.Sleep(sleeptime)
		return
		
